package com.zjpavt.client.hal;

import com.zjpavt.client.enums.LoopStatusEnum;
import com.zjpavt.client.nativemethod.JnIMethod;
import com.zjpavt.client.page.LoopGroupControlPage;
import com.zjpavt.client.page.PageManager;
import com.zjpavt.client.util.Consts;
import com.zjpavt.client.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Arrays;

/**
 * 键盘led灯光控制
 *
 * @author cjp
 */
@Slf4j
public class KeypadLedController {

    private static final Logger logger = LoggerFactory.getLogger(KeypadLedController.class);
    /**
     * 最小刷新事件  当小于该事件且没有发生变化的时候 可以忽略刷新灯的颜色
     */
    public static final int MIN_UPDATETIME = 1000;
    private static String lastCommand;
    private static long lastCommandChangeTime;
    /**
     * 键盘Led颜色枚举
     * 关闭，红色，绿色，蓝色，黄色，粉色，青色，白色
     */
    enum LedColor {
        CLOSE(0x0), RED(0x1), GREEN(0x2), BLUE(0x3), YELLOW(0x4), PINK(0x5), CYAN_BLUE(0x6), WHITE(0x7);
        private int colorVal;

        LedColor(int colorVal) {
            this.colorVal = colorVal;
        }

        public int getColorVal() {
            return colorVal;
        }
    }

    /**
     * 修改全部通道的LED状态
     *
     * @param status 所有的状态
     * @return 是否修改成功
     */
    public static boolean changeLedStatusAll(ArrayList<LedColor> status) {
        if (status == null || status.size() == 0) {
            logger.trace("led status empty");
            return false;
        }
        if (status.size() > Consts.DEFAULT_LOOP_NUM) {
            logger.trace("channel num out of led num");
            return false;
        }

        int[] colorVals = new int[status.size()];
        for (int i = 0; i < Math.min(LoopManager.getInstance().getLoopNum(), status.size()); i++) {
            //构造led颜色值数组
            colorVals[i] = status.get(i).getColorVal();
        }

        String colorString = StringUtil.commandInt2String(colorVals);
        if (lastCommand != null && lastCommand.equals(colorString) && lastCommandChangeTime + 1000 > System.currentTimeMillis()) {
            return true;
        }
        lastCommand = colorString;
        lastCommandChangeTime = System.currentTimeMillis();
        return JnIMethod.changeAllLedStatus(colorVals);
    }

    /**
     * 根据指令修改Led状态
     *
     * @return 是否修改成功
     */
    public static boolean changeLedStatusAllByCommand() {
        int[] command = LoopManager.getInstance().getEighthLoopStatus();
        int currentPrefixIndex = 0;
        ArrayList<LedColor> colorList;
        LoopGroupControlPage loopGroupControlPage = PageManager.getInstance().getLoopGroupControlPage();
        /*		log.info("current page num "+PageManager.getInstance().getCurrPageNum()
        				+ "== loop group page num:" + loopGroupControlPage.getPageNum());*/
//		如果当前在回路分组控制页面
        if (loopGroupControlPage != null && PageManager.getInstance().getCurrPageNum() + 1 == loopGroupControlPage.getPageNum()) {
            LoopGroupControlPage.LoopGroup currentLoopGroup = loopGroupControlPage.getCurrentLoopGroup();
//			firsi 从1开始 对于回路状态从0开始
            int start = currentLoopGroup.getFirstIndexInLoopManager() - 1;
            int end = currentLoopGroup.getFirstIndexInLoopManager() - 1 + currentLoopGroup.getSwitchSize();
            colorList = new ArrayList<>();
            for (int i = start; i < end; i++) {
                colorList.add(getColorByCommand(command[i]));
            }
        } else {
//			如果是正常页面上只使用前DEFAULT_LOOP_NUM个LED的状态
            colorList = new ArrayList<>();
            for (int i = 0; i < Math.min(command.length, Consts.DEFAULT_LOOP_NUM); i++) {
                colorList.add(getColorByCommand(command[i]));
            }
        }
        return changeLedStatusAll(colorList);
    }

    /**
     * 根据命令获取Led颜色
     *
     * @param command 获取指令
     * @return Led颜色
     */
    public final static LedColor getColorByCommand(int command) {
        LoopStatusEnum loopStatus = LoopStatusEnum.getLoopStatus(command);
        if (loopStatus == null) {
            logger.warn("getColorByCommand receive unknown status " +command);
            return LedColor.CLOSE;
        }
        switch (loopStatus) {
        case LOOP_STATUS_AUTO_OFF: {
            return LedColor.PINK;
        }
        case LOOP_STATUS_AUTO_ON: {
            return LedColor.BLUE;
        }
        case LOOP_STATUS_MANUAL_ON: {
            return LedColor.GREEN;
        }
        case LOOP_STATUS_MANUAL_OFF: {
            return LedColor.RED;
        }
        case LOOP_STATUS_ERROR: {
            return LedColor.CLOSE;
        }
        default: {
            return LedColor.CLOSE;
        }
        }
    }


    /**
     * 根据通道编号修改单个Led颜色
     *
     * @param channelNum start from 0
     * @param color 修改的颜色
     * @return 是否成功
     */
    public static boolean changeLedStatus(int channelNum, LedColor color) {
        if (channelNum < Consts.DEFAULT_LOOP_NUM && channelNum >= 0) {
            logger.trace("try to change led status: channelNum:" + channelNum + " Color:" + color.getColorVal());
            int y = channelNum / 8;
            int x = channelNum % 8;
            return changeLedStatus(x, y, color);
        } else {
            logger.trace("channelNum out of led num");
            return false;
        }
    }

    /**
     * 根据xy坐标来更改单个Led颜色（2行8列）
     *
     * @param x     led x坐标 0-7
     * @param y     led y坐标 0-1
     * @param color  修改的颜色
     * @return 是否成功
     */
    public static boolean changeLedStatus(int x, int y, LedColor color) {
        if (x < 0 || x > 7 || y < 0 || y > 1) {
            logger.trace("channelNum out of led num");
            return false;
        }
        int colorVal = color.getColorVal();
        logger.trace("changeLedStatus: x = " + x + " y = " + y + " " + colorVal);
        return JnIMethod.changeLedStatus(x, y, colorVal);
    }

    /**
     * 关闭所有LED
     */
    public static void closeAll() {
        int[] colorVals = new int[Consts.DEFAULT_LOOP_NUM];
        for (int i = 0; i < colorVals.length; i++) {
            //构造led颜色值数组
            colorVals[i] = LedColor.CLOSE.getColorVal();
        }
        JnIMethod.changeAllLedStatus(colorVals);
    }

}
